package com.base.custom

import android.content.Context
import android.graphics.*
import android.graphics.Shader.TileMode
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.palette.graphics.Palette
import kotlin.math.pow
import kotlin.math.sqrt


class PaletteView(context: Context, attrs: AttributeSet?, defStyleAttr: Int): View(context, attrs, defStyleAttr){
    constructor(context: Context): this(context, null)
    constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0)

    private val wheelPaint by lazy { val p = Paint();p.isAntiAlias = true;p }
    private val wheelRect = RectF()
    private val center = PointF()
    private var bitmap: Bitmap? = null
    private var size = 0
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        center.set(w / 2f, h / 2f)
        size = w.coerceAtMost(h)
        wheelRect.set(center.x - size/2f,center.y - size/2f,center.x + size/2f,center.y + size/2f)
        bitmap?.recycle()
        bitmap = createColorWheel(size)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas?:return
        bitmap?:return
        canvas.drawBitmap(bitmap!!,null,wheelRect,wheelPaint)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        event?:return super.onTouchEvent(event)
        if(getDistance(event.x,event.y) <= size/2f){
            val x1 = event.x - wheelRect.left
            val y1 = event.y - wheelRect.top
            val x = when{
                x1 + 1 > size -> size - 2
                x1 - 1 < 0 -> 0
                else -> (x1 - 1).toInt()
            }
            val y = when{
                y1 + 1 > size -> size - 2
                y1 - 1 < 0 -> 0
                else -> (y1 - 1).toInt()
            }

            val bitmap = Bitmap.createBitmap(bitmap?:return super.onTouchEvent(event),x,y,2,2)
            val color = Palette.from(bitmap).generate().getDominantColor(Color.WHITE)
            bitmap.recycle()
            call?.onCall(color)
        }
        return true
    }

    private fun createColorWheel(size: Int): Bitmap {
        val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
        val colorCount = 12
        val colorAngleStep = 360 / 12
        val colors = IntArray(colorCount + 1)
        val hsv = floatArrayOf(0f, 1f, 1f)
        for (i in colors.indices) {
            hsv[0] = (360 - i * colorAngleStep % 360).toFloat()
            colors[i] = Color.HSVToColor(hsv)
        }
        colors[colorCount] = colors[0]
        val sweepGradient = SweepGradient(size / 2f, size / 2f, colors, null)
        val radialGradient = RadialGradient(size / 2f, size / 2f, size/2f, -0x1, 0x00FFFFFF, TileMode.CLAMP)
        val composeShader = ComposeShader(sweepGradient, radialGradient, PorterDuff.Mode.SRC_OVER)
        val paint = Paint(Paint.ANTI_ALIAS_FLAG)
        paint.isAntiAlias = true
        paint.shader = composeShader
        val canvas = Canvas(bitmap)
        canvas.drawCircle(size / 2f, size / 2f, size/2f, paint)
        return bitmap
    }

    private fun getDistance(x1: Float,y1: Float) = sqrt((x1 - center.x).toDouble().pow(2.0) + (y1 - center.y).toDouble().pow(2.0))

    private var call: Call? = null
    fun setCall(call: Call?){
        this.call = call
    }
    interface Call{
        fun onCall(color: Int){

        }
    }

}